package geppetto.phraseHMM.phraseExtraction.phraseAccepter;


import geppetto.cat.alignments.Alignment;
import geppetto.cat.alignments.AlignmentsCache;
import geppetto.cat.alignments.AlignmentsSet;
import geppetto.cat.alignments.output.AlignerOutput;
import geppetto.cat.corpus.BilingualCorpus;
import geppetto.phraseHMM.WordTrie;
import geppetto.phraseHMM.lexicalWeighting.MosesLexicalWeightingCalculator;
import geppetto.phraseHMM.lexicalWeighting.UniformLexicalWeightingCalculator;
import geppetto.phraseHMM.phraseExtraction.GeneralPhraseExtraction;
import geppetto.phraseHMM.phraseExtraction.NoGlobalPruning;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.ExtractedPhrasePair;
import geppetto.phraseScorer.DirectionalModelPosterior;
import geppetto.phraseScorer.One;
import geppetto.phraseTable.PhraseTable;
import geppetto.reordering.AlwaysMonoCalculator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;



/**
 * Implements the phrase extraction of phillip Kohen the defaul of Moses. The
 * phrase extraction code extracts all phrase pairs that include at least one
 * aligned point but do not contradict an alignment by including an aligned word
 * in one language without its translation in the other language.
 * 
 * @author javg
 * 
 */
public class KohenPhraseAccept extends AbstractPhraseAccepter {

	AlignmentsSet _alignments;
	AlignmentsCache _cache;

	public KohenPhraseAccept(AlignmentsSet a) {
		_alignments = a;
		_cache = new AlignmentsCache(a);
	}

	// /**
	// * Does not accept null phrases
	// */
	// public boolean acceptNullPhrase(int sentenceNumber, byte sentenceSource,
	// int[] foreingSentence, int[] sourceSentence, int foreignStartPos, int
	// foreignEndPos, double score) {
	// return false;
	// }

	public boolean acceptPhrase(int sentenceNumber, byte sentenceSource,
			int[] foreingSentence, int[] sourceSentence, int sourceStartPos,
			int sourceEndPos, int foreignStartPos, int foreignEndPos,
			double score) {
		if(score <= 0) return false;
//		System.out.println("checking phrase " + sentenceNumber
//				+ " with starting pos = [" + sourceStartPos + ","
//				+ sourceEndPos + "," + foreignStartPos + "," + foreignEndPos
//				+ "]");
		// check if there is at least one aligned point
		Alignment al = _alignments.get(sentenceNumber);
		boolean hasSurePositions = false;
		for (int fpos = foreignStartPos; !hasSurePositions && fpos <= foreignEndPos; fpos++) {
			for (int spos = sourceStartPos; !hasSurePositions && spos <= sourceEndPos; spos++) {
				if (al.hasPosition(spos, fpos)) {
					hasSurePositions = true;
				}
			}
		}		
		// check if there is at least one aligned point
		if(hasSurePositions && !_cache.hasConflits(sentenceNumber, sourceStartPos, sourceEndPos, foreignStartPos, foreignEndPos)){
//			System.out.println("accepted");
			return true;
		}
		
//		System.out.println("rejected");
		return false;
	}


	@Override
	public boolean acceptPhrase(ExtractedPhrasePair epp) {
//		System.out.println("checking phrase " + sentenceNumber
//				+ " with starting pos = [" + sourceStartPos + ","
//				+ sourceEndPos + "," + foreignStartPos + "," + foreignEndPos
//				+ "]");
		// check if there is at least one aligned point
		int sentenceNumber = epp.getSentenceNumber();
		int foreignEndPos = epp.getForeignEndPos();
		int foreignStartPos = epp.getForeignStartPos();
		int sourceEndPos = epp.getSourceEndPos();
		int sourceStartPos = epp.getSourceStartPos();
		Alignment al = _alignments.get(sentenceNumber);
		boolean hasSurePositions = false;
		for (int fpos = foreignStartPos; !hasSurePositions && fpos <= foreignEndPos; fpos++) {
			for (int spos = sourceStartPos; !hasSurePositions && spos <= sourceEndPos; spos++) {
				if (al.hasPosition(spos, fpos)) {
					hasSurePositions = true;
				}
			}
		}		
		// check if there is at least one aligned point
		if(hasSurePositions && !_cache.hasConflits(sentenceNumber, sourceStartPos, sourceEndPos, foreignStartPos, foreignEndPos)){
//			System.out.println("accepted");
			return true;
		}
		
//		System.out.println("rejected");
		return false;
	}
	
	public static void main(String[] args) throws IOException {
		/*Alignment a = new Alignment(((byte) 0), ((byte) 0), 4, 4);
		System.out.println(a.toString());
		BilingualCorpus corpus = BilingualCorpus.getCorpusFromFileDescription(
				"/Users/javg/Projects/wa-data/ex/corpus.params", 6);
		AlignerOutput.outputGold(corpus.getGold().getAlignments().get(0),
				corpus, System.out);
		WordTrie sourcePhrasesVocab = new WordTrie(2);
		sourcePhrasesVocab.addPhrasesAllSentences(corpus._trainSourceSentences);
		sourcePhrasesVocab.compactTrie();
		System.out.println("source vocab built with "
				+ sourcePhrasesVocab._phraseCounter);
		WordTrie foreignPhrasesVocab = new WordTrie(2);
		foreignPhrasesVocab
				.addPhrasesAllSentences(corpus._trainForeignSentences);
		foreignPhrasesVocab.compactTrie();
		// PhraseTable pt = new PhraseTable(null,2,2,null,null);
		// GeneralPhraseExtraction.processSentence(pt, sentenceNumber,
		// sentenceSource, foreingSentence, sourceSentence, maxTargetDuration,
		// maxSourceDuration, scorer, accepter)
		PhraseTable pt = GeneralPhraseExtraction.build(corpus,
				BilingualCorpus.TRAIN_CORPUS, sourcePhrasesVocab,
				foreignPhrasesVocab, 2, 2, new GlobalProbabilityCalculator(),new One(), new KohenPhraseAccept(
						corpus.getGold()), new NoGlobalPruning(), new UniformLexicalWeightingCalculator());
		pt.printSimple(System.out);*/
	}

}
